home *** CD-ROM | disk | FTP | other *** search
/ Experimental BBS Explossion 3 / Experimental BBS Explossion III.iso / gus / vts139b.zip / SOUNDDEV.ASM < prev    next >
Assembly Source File  |  1993-12-22  |  29KB  |  903 lines

  1.                 IDEAL
  2.                 MODEL  TPascal
  3.                 LOCALS @@
  4.                 JUMPS
  5.  
  6.                 P286
  7.  
  8.                 DATASEG
  9.  
  10. MACRO SetBorder r,g,b
  11. MASM
  12. COMMENT %
  13.         PUSH    DX AX
  14.         MOV     DX,3C8h
  15.         XOR     AL,AL
  16.         OUT     DX,AL
  17.         INC     DX
  18.       IFDIF <&r>,<0>
  19.         MOV     AL,&r
  20.       ENDIF
  21.         OUT     DX,AL
  22.       IFDIF <&g>,<&r>
  23.         MOV     AL,&g
  24.       ENDIF
  25.         OUT     DX,AL
  26.       IFDIF <&b>,<&g>
  27.         MOV     AL,&b
  28.       ENDIF
  29.         OUT     DX,AL
  30.         POP     AX DX
  31. %
  32. IDEAL
  33. ENDM
  34.  
  35.  
  36. StackSize       EQU 1000
  37. DMABufferSize   EQU 2048
  38. FinalBufferSize EQU 4096
  39.  
  40. GLOBAL DevStack         : BYTE
  41. GLOBAL DevSS            : WORD
  42. GLOBAL DevSP            : WORD
  43.  
  44. GLOBAL OldTimerHandler  : DWORD
  45.  
  46. GLOBAL Sounding         : DWORD
  47. GLOBAL SoundLeft        : WORD
  48.  
  49. GLOBAL SystemClockIncr  : WORD
  50. GLOBAL SystemClockCount : WORD
  51.  
  52. GLOBAL PeriodicCount    : WORD
  53. GLOBAL PeriodicStart    : WORD
  54. GLOBAL PeriodicProc     : DWORD
  55.  
  56. GLOBAL DeviceIdling     : BYTE
  57.  
  58. GLOBAL NumChannels      : WORD
  59. GLOBAL BytesPerSample   : BYTE
  60.  
  61. GLOBAL DoBassPower      : BYTE
  62. GLOBAL MixMethod        : BYTE
  63.  
  64. GLOBAL DMABufferPtr     : DWORD
  65. GLOBAL DMABufferEnd     : WORD
  66. GLOBAL DMABuffer        : DWORD
  67. GLOBAL DMABufferYet     : BYTE
  68. GLOBAL DMAStopped       : BYTE
  69. GLOBAL DMAStop          : BYTE
  70. GLOBAL DMAIrqWatch      : BYTE
  71.  
  72. GLOBAL FinalBufferPos   : WORD
  73. GLOBAL FinalBuffer      : WORD
  74.  
  75. GLOBAL DeviceStartRut   : WORD
  76. GLOBAL DeviceRut1       : WORD
  77. GLOBAL DeviceRut2       : WORD
  78. GLOBAL DeviceKickRut    : WORD
  79. GLOBAL DeviceFillRut    : WORD
  80.  
  81. GLOBAL TrebleFilterVal_Left   : WORD
  82. GLOBAL TrebleFilterMult_Left  : WORD
  83. GLOBAL BassFilterVal_Left     : WORD
  84. GLOBAL BassFilterMult_Left    : WORD
  85. GLOBAL TrebleFilterVal_Right  : WORD
  86. GLOBAL TrebleFilterMult_Right : WORD
  87. GLOBAL BassFilterVal_Right    : WORD
  88. GLOBAL BassFilterMult_Right   : WORD
  89.  
  90.                 CODESEG
  91.  
  92. GLOBAL DoGetBuffer      : FAR
  93. GLOBAL GetDMACount      : NEAR
  94. GLOBAL InitTimer        : FAR
  95.  
  96.  
  97.  
  98.  
  99. ; ┌──────────────────────────────────────────────────────────────────────────┐
  100. ; │                                                                          │
  101. ; │ MACRO: Saturate                                                          │
  102. ; │                                                                          │
  103. ; │ Macro that saturates a sample just after an addition.                    │
  104. ; │                                                                          │
  105. ; │ IN:  Reg    = Register to be saturated.                                  │
  106. ; │                                                                          │
  107. ; └──────────────────────────────────────────────────────────────────────────┘
  108.  
  109. MACRO Saturate Reg
  110. LOCAL @@posit, @@nooverf
  111.  
  112.                 JNO     SHORT @@nooverf
  113.                 JS      SHORT @@posit
  114.                  MOV    Reg,-32767
  115.                 JMP     SHORT @@nooverf
  116. @@posit:         MOV    Reg,32767
  117. @@nooverf:
  118.  
  119. ENDM Saturate
  120.  
  121.  
  122.  
  123.  
  124.              INCLUDE "BASSPOW.INC"
  125.              INCLUDE "MIXROUTS.INC"
  126.  
  127.  
  128.  
  129.  
  130. MACRO DevCall DevRut, Segm
  131.  
  132.                 JMP     [DevRut]  ; Segm:
  133. DevRut&Ret:
  134.  
  135. ENDM
  136.  
  137.  
  138.  
  139.  
  140. ; ┌──────────────────────────────────────────────────────────────────────────┐
  141. ; │                                                                          │
  142. ; │ ROUTINE: DMAFillBuffer                                                   │
  143. ; │                                                                          │
  144. ; │ This routine fills a portion of the DMA buffer with the whole buffer of  │
  145. ; │ samples pointed to by Sounding & SoundLeft.                              │
  146. ; │                                                                          │
  147. ; │ IN:  nothing                                                             │
  148. ; │                                                                          │
  149. ; │ OUT: nothing                                                             │
  150. ; │                                                                          │
  151. ; │ MODIFIES: AX, BX, CX, DX, SI, DI, ES                                     │
  152. ; │                                                                          │
  153. ; └──────────────────────────────────────────────────────────────────────────┘
  154.  
  155. DeviceIdCount   DB 0
  156. TickCnt         DB 0
  157.  
  158. PUBLIC DMAFillBuffer
  159.  
  160. DMAFillBuffer:
  161.                 XOR     AL,AL
  162.                 MOV     [CS:DeviceIdCount],AL
  163.  
  164.                 CALL    CalcNewMixData
  165.                 MOV     CX,[SoundLeft]
  166.                 MOV     AL,[BytesPerSample]
  167.                 MOV     DX,CX
  168.                 XOR     AH,AH
  169.                 MUL     DX
  170.                 LES     DI,[DMABufferPtr]
  171.                 MOV     BX,[DMABufferEnd]
  172.                 LDS     SI,[Sounding]
  173.                 CLD
  174.  
  175.                 ADD     AX,DI
  176.                 CMP     AX,BX
  177.                 JBE     SHORT @@end
  178.                  SUB    BX,DI
  179.                  JZ     SHORT @@skip1st
  180.                   PUSH  CX
  181.                   MOV   AX,BX
  182.                   MOV   CL,[SS:BytesPerSample]
  183.                   XOR   CH,CH
  184.                   XOR   DX,DX
  185.                   DIV   CX
  186.                   MOV   CX,AX
  187.                   PUSH  CX
  188.                   CALL  [SS:DeviceFillRut]
  189.                   POP   BX
  190.                   POP   CX
  191.                   SUB   CX,BX
  192. @@skip1st:       MOV    DI,[WORD PTR SS:DMABuffer]
  193. @@end:          CALL    [SS:DeviceFillRut]
  194.  
  195. ;MOV AL,[CS:TickCnt]
  196. ;XOR AL,255
  197. ;MOV [CS:TickCnt],AL
  198. ;MOV [ES:DI-1],AL
  199.  
  200.                 MOV     AX,SS
  201.                 MOV     DS,AX
  202.                 MOV     [WORD PTR DMABufferPtr],DI
  203.                 RET
  204.  
  205.  
  206.  
  207.  
  208. ; ┌──────────────────────────────────────────────────────────────────────────┐
  209. ; │                                                                          │
  210. ; │ ROUTINE: DMADoGetBuff                                                    │
  211. ; │                                                                          │
  212. ; │ This is the main buffer-filling routine for DMA devices. First it calls  │
  213. ; │ the buffer grabber. Then, it checks to see if the DMA has advanced       │
  214. ; │ enough to leave space for this buffer.                                   │
  215. ; │                                                                          │
  216. ; │ IN:  nothing                                                             │
  217. ; │                                                                          │
  218. ; │ OUT: nothing                                                             │
  219. ; │                                                                          │
  220. ; │ MODIFIES: AX, BX, CX, DX, SI, DI, ES                                     │
  221. ; │                                                                          │
  222. ; └──────────────────────────────────────────────────────────────────────────┘
  223.  
  224. PUBLIC DMADoGetBuff
  225.  
  226. DMADoGetBuff:
  227.  
  228.                 MOV     AX,[SoundLeft]
  229.                 MOV     BL,[DMABufferYet]
  230.                 AND     BL,BL
  231.                 JZ      SHORT @@1
  232.                  CALL   DoGetBuffer
  233. @@1:            MOV     BL,1
  234.                 MOV     [DMABufferYet],BL
  235.  
  236.                 CMP     AX,10
  237.                 JC      SHORT @@end
  238.  
  239.                 MOV     DL,[BytesPerSample]
  240.                 XOR     DH,DH
  241.                 MUL     DX
  242.  
  243.                 PUSH    AX
  244.                 CALL    GetDMACount
  245.                 MOV     BX,DMABufferSize
  246.                 SUB     BX,AX
  247.                 ADD     BX,[WORD PTR DMABuffer]
  248.                 MOV     CX,BX
  249.                 SUB     BX,[WORD PTR DMABufferPtr]
  250.                 JNC     SHORT @@2
  251.                  ADD    BX,DMABufferSize
  252. @@2:            POP     AX
  253.                 SUB     BX,AX
  254.                 JNC     DMAFillBuffer
  255.  
  256.                 XOR     BL,BL
  257.                 MOV     [DMABufferYet],BL
  258. @@end:
  259.                 MOV     AL,[CS:DeviceIdCount]
  260.                 CMP     AL,20
  261.                 JNC     @@end1
  262.                 INC     [CS:DeviceIdCount]
  263. @@end1:
  264.                 MOV     [DeviceIdling],AL
  265.  
  266.                 RET
  267.  
  268.  
  269.  
  270.  
  271. ;                MOV     [DevSS],SS
  272. ;                MOV     [DevSP],SP
  273. ;                MOV     DX,DS
  274. ;                MOV     SS,DX
  275. ;                MOV     SP,OFFSET DevStack + StackSize
  276.  
  277. ;                MOV     SS,[DevSS]
  278. ;                MOV     SP,[DevSP]
  279.  
  280.  
  281.  
  282.  
  283. ; ┌──────────────────────────────────────────────────────────────────────────┐
  284. ; │                                                                          │
  285. ; │ ROUTINE: TimerHandler                                                    │
  286. ; │                                                                          │
  287. ; │ This is the big routine for non-DMA devices. It is called through        │
  288. ; │ interrupts from a timer whose period is the sampling period.             │
  289. ; │                                                                          │
  290. ; └──────────────────────────────────────────────────────────────────────────┘
  291.  
  292. PUBLIC TimerHandler
  293.  
  294. TimerHandler:
  295.         CLI   ; Just for safety's sake.
  296.  
  297.                 ; ┌────────────────────────────────────────────┐
  298.                 ; │ Startup:                                   │
  299.                 ; │                                            │
  300.                 ; │   - Save the registers in the local stack. │
  301.                 ; │   - Set the data segment register.         │
  302.                 ; └────────────────────────────────────────────┘
  303.  
  304.                 PUSH    AX
  305.                 PUSH    BX
  306.                 PUSH    CX
  307.                 PUSH    DX
  308.                 PUSH    DI
  309.                 PUSH    SI
  310.                 PUSH    DS
  311.  
  312.                 MOV     AX,SEG Sounding
  313.                 MOV     DS,AX
  314.  
  315.                 ; ┌──────────────────────────────────────────┐
  316.                 ; │ First, we jump to the device start code. │
  317.                 ; └──────────────────────────────────────────┘
  318.  
  319.                 DevCall DeviceStartRut
  320.  
  321.                 ; ┌───────────────────────────────────────────┐
  322.                 ; │ Check to see if there are samples to use. │
  323.                 ; └───────────────────────────────────────────┘
  324.                 
  325.                 MOV     AX,[SoundLeft]
  326.                 AND     AX,AX
  327.                 JZ      SHORT thAfterProcessingSample
  328.  
  329.                 ; ┌──────────────────────────────────────────────┐
  330.                 ; │ Decrement the number of samples left in the  │
  331.                 ; │ buffer, do the device initialization if any, │
  332.                 ; │ and signal that the device is not idle.      │
  333.                 ; └──────────────────────────────────────────────┘
  334.  
  335.                 DEC     AX
  336.                 MOV     [SoundLeft],AX
  337.  
  338.                 DevCall DeviceRut1
  339.  
  340.                 XOR     BH,BH
  341.                 MOV     [DeviceIdling],BH
  342.  
  343.                 ; ┌─────────────────────────────────┐
  344.                 ; │ Load the buffer pointer, do the │
  345.                 ; │ mixing and output the sample.   │
  346.                 ; └─────────────────────────────────┘
  347.                 
  348.                 LDS     SI,[Sounding]
  349.  
  350.                 CALL    MixChannels
  351.  
  352.                 MOV     DX,SEG Sounding
  353.                 MOV     DS,DX
  354.                 MOV     [WORD PTR Sounding],SI
  355.  
  356.                 MOV     SI,OFFSET FinalBuffer
  357.                 MOV     CX,[FinalBufferPos]
  358.                 ADD     SI,CX
  359.                 ADD     SI,CX
  360.                 MOV     [SI],AX
  361.                 INC     CX
  362.                 AND     CX,FinalBufferSize - 1
  363.                 MOV     [FinalBufferPos],CX
  364.  
  365.                 DevCall DeviceRut2
  366.  
  367.                 ; ┌────────────────────┐
  368.                 ; │ Restore the stack. │
  369.                 ; └────────────────────┘
  370.  
  371. thAfterProcessingSample:
  372. sti
  373.                 ; ┌────────────────────────────┐
  374.                 ; │ Check if the old interrupt │
  375.                 ; │ routine must be called.    │
  376.                 ; └────────────────────────────┘
  377.  
  378.                 MOV     AX,[SystemClockIncr]
  379.                 ADD     [SystemClockCount],AX
  380.                 JC      SHORT @@SystemClock
  381.  
  382.                 ; ┌──────────────────────────────────┐
  383.                 ; │ Else, signal the EOI to the PIC. │
  384.                 ; └──────────────────────────────────┘
  385.  
  386.                 MOV     AL,20h
  387.                 OUT     20h,AL
  388.  
  389. @@CheckOutProc:
  390.                 MOV     CX,[PeriodicCount]
  391.                 JCXZ    SHORT @@OutProc
  392.                 DEC     CX
  393.                 MOV     [PeriodicCount],CX
  394.                 JZ      SHORT @@OutProc
  395.  
  396.                 MOV     AX,[SoundLeft]
  397.                 AND     AX,AX
  398.                 JZ      SHORT @@OutProc
  399.  
  400. @@exit:
  401.                 ; ┌────────────────────────────────────┐
  402.                 ; │ Do the final stuff: Pop registers. │
  403.                 ; └────────────────────────────────────┘
  404.  
  405.                 POP     DS
  406.                 POP     SI
  407.                 POP     DI
  408.                 POP     DX
  409.                 POP     CX
  410.                 POP     BX
  411.                 POP     AX
  412.                 IRET
  413.  
  414. @@SystemClock:
  415.                 PUSHF
  416.                 CALL    [OldTimerHandler]
  417.                 JMP     SHORT @@CheckOutProc
  418.  
  419. @@OutProc:
  420.                 ; ┌────────────────────────────────────────────┐
  421.                 ; │ Get a new sample buffer. If there is none, │
  422.                 ; │ signal that the device is in idle state.   │
  423.                 ; └────────────────────────────────────────────┘
  424.  
  425.                 MOV     AL,0
  426. @@outsemaph:
  427.                 AND     AL,AL
  428.                 JNZ     SHORT @@exit
  429.                 INC     AL
  430.                 MOV     [BYTE PTR CS:@@outsemaph-1],AL
  431.  
  432.                 MOV     AX,[SoundLeft]
  433.                 AND     AX,AX
  434.                 JNZ     SHORT @@NoIdle
  435.  
  436.                 CALL    CalcNewMixData
  437.  
  438.                 PUSH    ES
  439.                 CALL    DoGetBuffer
  440.                 POP     ES
  441.  
  442.                 CALL    CalcNewMixData
  443.  
  444.                 MOV     AX,[SoundLeft]
  445.                 AND     AX,AX
  446.                 JNZ     SHORT @@NoIdle
  447.  
  448.                 INC     AH
  449.                 MOV     [DeviceIdling],AH
  450.  
  451. @@NoIdle:
  452.                 MOV     [BYTE PTR CS:@@outsemaph-1],0
  453.  
  454.                 ; ┌─────────────────────────────────────────────┐
  455.                 ; │ See if the periodic process must be called. │
  456.                 ; └─────────────────────────────────────────────┘
  457.                 
  458.                 MOV     AX,[PeriodicCount]
  459.                 AND     AX,AX
  460.                 JNZ     SHORT @@NoPeriodic
  461.  
  462.                 MOV     AX,[PeriodicStart]
  463.                 MOV     [PeriodicCount],AX
  464.  
  465.                 ; ┌────────────────────────────┐
  466.                 ; │ Call the periodic process. │
  467.                 ; └────────────────────────────┘
  468.  
  469.                 PUSH    ES
  470.                 STI
  471.                 CALL    [PeriodicProc]
  472.                 POP     ES
  473.  
  474. @@NoPeriodic:
  475.                 JMP     SHORT @@exit
  476.  
  477.  
  478.  
  479.  
  480. ; ┌──────────────────────────────────────────────────────────────────────────┐
  481. ; │                                                                          │
  482. ; │ ROUTINE: DMATimerHandler                                                 │
  483. ; │                                                                          │
  484. ; │ This is the big routine for DMA devices. It is called through            │
  485. ; │ interrupts from a timer whose period is a few Hertz (100 for example).   │
  486. ; │                                                                          │
  487. ; └──────────────────────────────────────────────────────────────────────────┘
  488.  
  489. DMASema         DB 0
  490.  
  491. PUBLIC DMATimerHandler
  492.  
  493. DMATimerHandler:
  494.                 CLI   ; Just for safety's sake.
  495.  
  496.                 ; ┌─────────────────────────┐
  497.                 ; │ Startup:                │
  498.                 ; │                         │
  499.                 ; │   - Save the registers. │
  500.                 ; └─────────────────────────┘
  501.  
  502.                 PUSHA
  503.                 PUSH    ES
  504.                 PUSH    DS
  505.  
  506.                 MOV     AX,SEG Sounding
  507.                 MOV     DS,AX
  508.  
  509. @@DoSystemClock:
  510.  
  511.                 ; ┌────────────────────────────────────────────────────┐
  512.                 ; │ Check if the old interrupt routine must be called. │
  513.                 ; └────────────────────────────────────────────────────┘
  514.  
  515.                 MOV     AX,[SystemClockIncr]
  516.                 ADD     [SystemClockCount],AX
  517.                 JNC     SHORT @@NoSysClk
  518.  
  519.                 ; ┌───────────────┐
  520.                 ; │ If so, do it. │
  521.                 ; └───────────────┘
  522.  
  523.                 PUSHF
  524.                 CALL    [OldTimerHandler]
  525.                 JMP     SHORT @@SystemClkDone
  526.  
  527. @@NoSysClk:
  528.                 ; ┌──────────────────────────────────┐
  529.                 ; │ Else, signal the EOI to the PIC. │
  530.                 ; └──────────────────────────────────┘
  531.  
  532.                 MOV     AL,20h
  533.                 OUT     20h,AL
  534.  
  535. @@SystemClkDone:
  536.                 CLI
  537.  
  538.                 ; ┌─────────────────────────────────────────┐
  539.                 ; │ First we check if the DMA operation is  │
  540.                 ; │ requested to stop. If so, we signal the │
  541.                 ; │ stopping of the DMA and jump to the old │
  542.                 ; │ IRQ-checking part.                      │
  543.                 ; └─────────────────────────────────────────┘
  544.  
  545.                 MOV     AL,[DMAStop]
  546.                 AND     AL,AL
  547.                 JZ      SHORT @@notstop
  548. ;                 MOV    [DMAStopped],AL
  549.                  MOV    [DeviceIdling],AL
  550.                  JMP    SHORT @@end
  551. @@notstop:
  552.                 ; ┌─────────────────────────────────────────┐
  553.                 ; │ Now, we check the IRQ watchdog, just in │
  554.                 ; │ case we need to kick the card.          │
  555.                 ; └─────────────────────────────────────────┘
  556.  
  557. MASM
  558. COMMENT #
  559.  
  560.                 MOV     AL,[DMAIrqWatch]
  561.                 CMP     AL,200
  562.                 JC      SHORT @@notwatch
  563. ;                 CALL   [DeviceKickRut]
  564. @@notwatch:
  565.                 ; ┌─────────────────────────────────────────┐
  566.                 ; │ If the device is said to be idle, reset │
  567.                 ; │ the timer. This is to protect the timer │
  568.                 ; │ period from being modified.             │
  569.                 ; └─────────────────────────────────────────┘
  570.  
  571.                 MOV     AL,[DeviceIdling]
  572.                 AND     AL,AL
  573.                 JZ      SHORT @@notidling
  574. ;                 CALL    InitTimer
  575. @@notidling:
  576.                 ; ┌────────────────────────────────────────┐
  577.                 ; │ Signal that the device is not idling,  │
  578.                 ; │ and fill a bit more of the DMA buffer. │
  579.                 ; └────────────────────────────────────────┘
  580. #
  581. IDEAL
  582.                 MOV     AL,[CS:DMASema]
  583.                 AND     AL,AL
  584.                 JNZ     @@end
  585.  
  586.                 INC     [CS:DMASema]
  587.                 STI
  588.  
  589. @@loop:
  590.  
  591.                 PUSH    DS
  592.                 MOV     AX,0B800h
  593.                 MOV     DS,AX
  594.                 INC     [WORD PTR DS:90*4];
  595.                 POP     DS
  596.  
  597.                 MOV     [DevSS],SS
  598.                 MOV     [DevSP],SP
  599.                 MOV     DX,DS
  600.                 MOV     SS,DX
  601.                 MOV     SP,OFFSET DevStack + StackSize
  602.  
  603.                 XOR     AL,AL
  604.                 MOV     [DeviceIdling],AL
  605.  
  606. ;SetBorder 0, 63, 63
  607.  
  608.                 STI
  609.                 CALL    DMADoGetBuff
  610.                 CLI
  611.  
  612. ;SetBorder 0, 0, 63
  613.  
  614.                 ; ┌─────────────────────────────────────┐
  615.                 ; │ Call the periodic process and exit. │
  616.                 ; └─────────────────────────────────────┘
  617.  
  618.                 STI
  619.                 CALL    [PeriodicProc]
  620.                 CLI
  621.  
  622.                 MOV     SS,[DevSS]
  623.                 MOV     SP,[DevSP]
  624.  
  625.                 MOV     AL,[CS:DeviceIdCount]
  626.                 AND     AL,AL
  627. ;                JZ      @@loop
  628.  
  629.                 DEC     [CS:DMASema]
  630.  
  631. @@end:
  632.                 ; ┌────────────────────────────────────────┐
  633.                 ; │ Increment the watchdog, but don't let  │
  634.                 ; │ it wrap around.                        │
  635.                 ; └────────────────────────────────────────┘
  636.  
  637.                 MOV     AL,[DMAIrqWatch]
  638.                 CMP     AL,250
  639.                 JNC     SHORT @@noinc
  640.                  INC    [DMAIrqWatch]
  641. @@noinc:
  642.  
  643.                 ; ┌────────────────────────────────────────────────┐
  644.                 ; │ Do the final stuff: Pop registers, restore the │
  645.                 ; │ stack, and exit.                               │
  646.                 ; └────────────────────────────────────────────────┘
  647.  
  648.                 POP     DS
  649.                 POP     ES
  650.                 POPA
  651.                 IRET
  652.  
  653.  
  654.  
  655.  
  656.  
  657. MASM
  658. COMMENT ~
  659.  
  660. kk:
  661.  
  662.                 CLI   ; Just for safety's sake.
  663.  
  664.                 ; ┌─────────────────────────┐
  665.                 ; │ Startup:                │
  666.                 ; │                         │
  667.                 ; │   - Save the registers. │
  668.                 ; └─────────────────────────┘
  669.  
  670.                 PUSHA
  671.                 PUSH    ES
  672.                 PUSH    DS
  673.  
  674.                 MOV     AX,SEG Sounding
  675.                 MOV     DS,AX
  676.  
  677. @@DoSystemClock:
  678.  
  679.                 ; ┌────────────────────────────────────────────────────┐
  680.                 ; │ Check if the old interrupt routine must be called. │
  681.                 ; └────────────────────────────────────────────────────┘
  682.  
  683.                 MOV     AX,[SystemClockIncr]
  684.                 ADD     [SystemClockCount],AX
  685.                 JNC     SHORT @@NoSysClk
  686.  
  687.                 ; ┌───────────────┐
  688.                 ; │ If so, do it. │
  689.                 ; └───────────────┘
  690.  
  691.                 PUSHF
  692.                 CALL    [OldTimerHandler]
  693.                 JMP     SHORT @@SystemClkDone
  694.  
  695. @@NoSysClk:
  696.                 ; ┌──────────────────────────────────┐
  697.                 ; │ Else, signal the EOI to the PIC. │
  698.                 ; └──────────────────────────────────┘
  699.  
  700.                 MOV     AL,20h
  701.                 OUT     20h,AL
  702.  
  703. @@SystemClkDone:
  704.                 CLI
  705.  
  706.                 ; ┌─────────────────────────────────────────┐
  707.                 ; │ First we check if the DMA operation is  │
  708.                 ; │ requested to stop. If so, we signal the │
  709.                 ; │ stopping of the DMA and jump to the old │
  710.                 ; │ IRQ-checking part.                      │
  711.                 ; └─────────────────────────────────────────┘
  712.  
  713.                 MOV     AL,[DMAStop]
  714.                 AND     AL,AL
  715.                 JZ      SHORT @@notstop
  716. ;                 MOV    [DMAStopped],AL
  717.                  MOV    [DeviceIdling],AL
  718.                  JMP    SHORT @@end
  719. @@notstop:
  720.                 ; ┌─────────────────────────────────────────┐
  721.                 ; │ Now, we check the IRQ watchdog, just in │
  722.                 ; │ case we need to kick the card.          │
  723.                 ; └─────────────────────────────────────────┘
  724.  
  725.                 MOV     AL,[DMAIrqWatch]
  726.                 CMP     AL,200
  727.                 JC      SHORT @@notwatch
  728. ;                 CALL   [DeviceKickRut]
  729. @@notwatch:
  730.                 ; ┌─────────────────────────────────────────┐
  731.                 ; │ If the device is said to be idle, reset │
  732.                 ; │ the timer. This is to protect the timer │
  733.                 ; │ period from being modified.             │
  734.                 ; └─────────────────────────────────────────┘
  735.  
  736.                 MOV     AL,[DeviceIdling]
  737.                 AND     AL,AL
  738.                 JZ      SHORT @@notidling
  739. ;                 CALL    InitTimer
  740. @@notidling:
  741.                 ; ┌────────────────────────────────────────┐
  742.                 ; │ Signal that the device is not idling,  │
  743.                 ; │ and fill a bit more of the DMA buffer. │
  744.                 ; └────────────────────────────────────────┘
  745.  
  746.                 MOV     AL,[CS:DMASema]
  747.                 AND     AL,AL
  748.                 JNZ     @@end
  749.  
  750.                 INC     [CS:DMASema]
  751.                 STI
  752.  
  753. @@loop:
  754.  
  755.                 PUSH    DS
  756.                 MOV     AX,0B800h
  757.                 MOV     DS,AX
  758.                 INC     [WORD PTR DS:90*4];
  759.                 POP     DS
  760.  
  761.                 MOV     [DevSS],SS
  762.                 MOV     [DevSP],SP
  763.                 MOV     DX,DS
  764.                 MOV     SS,DX
  765.                 MOV     SP,OFFSET DevStack + StackSize
  766.  
  767.                 XOR     AL,AL
  768.                 MOV     [DeviceIdling],AL
  769.  
  770. ;SetBorder 0, 63, 63
  771.  
  772.                 STI
  773.                 CALL    DMADoGetBuff
  774.                 CLI
  775.  
  776. ;SetBorder 0, 0, 63
  777.  
  778.                 ; ┌─────────────────────────────────────┐
  779.                 ; │ Call the periodic process and exit. │
  780.                 ; └─────────────────────────────────────┘
  781.  
  782.                 STI
  783.                 CALL    [PeriodicProc]
  784.                 CLI
  785.  
  786.                 MOV     SS,[DevSS]
  787.                 MOV     SP,[DevSP]
  788.  
  789.                 MOV     AL,[CS:DeviceIdCount]
  790.                 AND     AL,AL
  791. ;                JZ      @@loop
  792.  
  793.                 DEC     [CS:DMASema]
  794.  
  795. @@end:
  796.                 ; ┌────────────────────────────────────────┐
  797.                 ; │ Increment the watchdog, but don't let  │
  798.                 ; │ it wrap around.                        │
  799.                 ; └────────────────────────────────────────┘
  800.  
  801.                 MOV     AL,[DMAIrqWatch]
  802.                 CMP     AL,250
  803.                 JNC     SHORT @@noinc
  804.                  INC    [DMAIrqWatch]
  805. @@noinc:
  806.  
  807.                 ; ┌────────────────────────────────────────────────┐
  808.                 ; │ Do the final stuff: Pop registers, restore the │
  809.                 ; │ stack, and exit.                               │
  810.                 ; └────────────────────────────────────────────────┘
  811.  
  812.                 POP     DS
  813.                 POP     ES
  814.                 POPA
  815.                 IRET
  816.  
  817. ~
  818. IDEAL
  819.  
  820.  
  821.  
  822.  
  823.  
  824. PUBLIC NullTimerHandler
  825. NullTimerHandler:
  826.                 PUSHA
  827.                 PUSH    DS
  828.                 PUSH    ES
  829.  
  830.                 MOV     AX,SEG Sounding
  831.                 MOV     DS,AX
  832.  
  833.                 MOV     [DevSS],SS
  834.                 MOV     [DevSP],SP
  835.                 MOV     DX,DS
  836.                 MOV     SS,DX
  837.                 MOV     SP,OFFSET DevStack + StackSize
  838.  
  839. @@DoSystemClock:
  840.  
  841.                 ; ┌────────────────────────────────────────────────────┐
  842.                 ; │ Check if the old interrupt routine must be called. │
  843.                 ; └────────────────────────────────────────────────────┘
  844.  
  845.                 MOV     AX,[SystemClockIncr]
  846.                 ADD     [SystemClockCount],AX
  847.                 JNC     SHORT @@NoSysClk
  848.  
  849.                 ; ┌───────────────┐
  850.                 ; │ If so, do it. │
  851.                 ; └───────────────┘
  852.  
  853.                 PUSHF
  854.                 CALL    [OldTimerHandler]
  855.                 JMP     SHORT @@SystemClkDone
  856.  
  857. @@NoSysClk:
  858.                 ; ┌──────────────────────────────────┐
  859.                 ; │ Else, signal the EOI to the PIC. │
  860.                 ; └──────────────────────────────────┘
  861.  
  862.                 MOV     AL,20h
  863.                 OUT     20h,AL
  864.  
  865. @@SystemClkDone:
  866.                 CALL    [PeriodicProc]
  867.  
  868.                 MOV     SS,[DevSS]
  869.                 MOV     SP,[DevSP]
  870.  
  871.                 POP     ES
  872.                 POP     DS
  873.                 POPA
  874.                 IRET
  875.  
  876.  
  877.  
  878.  
  879.  
  880.  
  881. ; ┌──────────────────────────────────────────────────────────────────────────┐
  882. ; │                                                                          │
  883. ; │ ROUTINE: NullDevRut                                                      │
  884. ; │                                                                          │
  885. ; │ Do-nothing routine for the unused device services.                       │
  886. ; │                                                                          │
  887. ; └──────────────────────────────────────────────────────────────────────────┘
  888.  
  889. NullDevRut:
  890.                 RET
  891.  
  892.  
  893.  
  894.  
  895.                 INCLUDE "DEVSB.INC"
  896.                 INCLUDE "DEVSPKR.INC"
  897.                 INCLUDE "DEVDAC.INC"
  898.  
  899.  
  900.  
  901.  
  902. END
  903.